<?php
//版权所有(C) 2014 www.ilinei.com

namespace ilinei;

class upload{
	private $attachdir = '';
	public  $attach = array();
	private $type = '';
	private $extid = 0;
	private $errorcode = 0;
	private $forcename = '';
	private $targetdirs = array('forum', 'album', 'portal', 'common', 'temp', 'b2c', 'cms', 'ad', 'mutual', 'wm', 'product', 'doc', 'act', 'site');
	
	public function __construct($attachdir = '/attachment') {
		$this->attachdir = ROOTPATH.$attachdir;
	}
	
	public function init($attach, $type = 'temp', $extid = 0, $forcename = '') {
		if(!is_array($attach) || empty($attach) || !$this->is_upload_file($attach['tmp_name']) || trim($attach['name']) == '' || $attach['size'] == 0){
			$this->attach = array();
			$this->errorcode = -1;
			return false;
		}else{
			$this->type = $this->check_dir_type($type);
			$this->extid = intval($extid);
			$this->forcename = $forcename;
			
			$attach['size'] = intval($attach['size']);
			$attach['name'] =  trim($attach['name']);
			$attach['thumb'] = '';
			$attach['ext'] = $this->fileext($attach['name']);
			
			$attach['name'] =  htmlspecialchars($attach['name'], ENT_QUOTES);
			if(strlen($attach['name']) > 90) $attach['name'] = cutstr($attach['name'], 80, '').'.'.$attach['ext'];
			
			$attach['isimage'] = $this->is_image_ext($attach['ext']);
			$attach['extension'] = $this->get_target_extension($attach['ext']);
			$attach['attachdir'] = $this->get_target_dir($this->type, $extid);
			$attach['attachment'] = $attach['attachdir'].$this->get_target_filename($this->type, $this->extid, $this->forcename).'.'.$attach['extension'];
			$attach['target'] = $this->type.'/'.$attach['attachment'];
			$this->attach = & $attach;
			$this->errorcode = 0;
			
			return true;
		}
	}
	
	public function save() {
		if(empty($this->attach) || empty($this->attach['tmp_name']) || empty($this->attach['target']))  $this->errorcode = -101;
		elseif(in_array($this->type, array( 'album')) && !$this->attach['isimage'])  $this->errorcode = -102;
		elseif(!$this->save_to_local($this->attach['tmp_name'], $this->attachdir.'/'.$this->attach['target'])) $this->errorcode = -103;
		else {
			$this->errorcode = 0;
			return true;
		}
		
		return false;
	}
	
	public function error() {
		return $this->errorcode;
	}
	
	public function get_image_info($target, $allowswf = false) {
		$ext = $this->fileext($target);
		$isimage = $this->is_image_ext($ext);
		if(!$isimage && ($ext != 'swf' || !$allowswf)) return false;
		elseif(!is_readable($target))  return false;
		elseif($imageinfo = @getimagesize($target)) {
			list($width, $height, $type) = !empty($imageinfo) ? $imageinfo : array('', '', '');
			$size = $width * $height;
			if($size > 16777216 || $size < 16 )  return false;
			elseif($ext == 'swf' && $type != 4)  return false;
			elseif($isimage && !in_array($type, array(1,2,3,6,13)))  return false;
			return $imageinfo;
		} else return false;
	}
	
	public function get_target_filename($type, $extid = 0, $forcename = '') {
		if($type == 'common' && $forcename != '')  $filename = $type.'_'.intval($extid).($forcename != '' ? "_$forcename" : '');
		else $filename = date('His').strtolower(random(16));
		return $filename;
	}
	
	public function get_target_extension($ext) {
		static $safeext  = array(
		'attach', 'swf', 
		'jpg', 'jpeg', 'gif', 'png', 'bmp', 
		'zip', 'rar', 
		'mp3', 'flv', 'mp4', 
		'txt', 'xml', 'pem', 'css', 'js', 'htm', 'html', 'java', 'cs', 'h', 
		'xlt', 'xls', 'xlsx', 'doc', 'docx', 'pdf', 
		'psd', 'ai');
		
		return strtolower(!in_array(strtolower($ext), $safeext) ? 'attach' : $ext);
	}
	
	public function get_target_dir($type, $extid = '', $check_exists = true) {
		$subdir = $subdir1 = $subdir2 = '';
		if(in_array($type, $this->targetdirs)){
			$subdir1 = date('Ym');
			$subdir2 = date('d');
			$subdir = $subdir1.'/'.$subdir2.'/';
		}elseif($type == 'common')  $subdir = $subdir1 = substr(md5($extid), 0, 2).'/';
		
		$check_exists && $this->check_dir_exists($type, $subdir1, $subdir2);
		
		return $subdir;
	}
	
	private function fileext($filename) {
		return addslashes(strtolower(substr(strrchr($filename, '.'), 1, 10)));
	}
	
	private function is_image_ext($ext) {
		static $imgext  = array('jpg', 'jpeg', 'gif', 'png', 'bmp');
		return in_array($ext, $imgext) ? 1 : 0;
	}
	
	private function is_upload_file($source) {
		return $source && ($source != 'none') && (is_uploaded_file($source) || is_uploaded_file(str_replace('\\\\', '\\', $source)));
	}

	private function check_dir_type($type) {
		return !in_array($type, $this->targetdirs) ? 'temp' : $type;
	}

	private function check_dir_exists($type = '', $sub1 = '', $sub2 = '') {
		$type = $this->check_dir_type($type);
		
		$basedir = $this->attachdir;
		$typedir = $type ? ($basedir.'/'.$type) : '';
		$subdir1  = $type && $sub1 !== '' ?  ($typedir.'/'.$sub1) : '';
		$subdir2  = $sub1 && $sub2 !== '' ?  ($subdir1.'/'.$sub2) : '';
		
		$res = $subdir2 ? is_dir($subdir2) : ($subdir1 ? is_dir($subdir1) : is_dir($typedir));
		if(!$res) {
			$res = $typedir && $this->make_dir($typedir);
			$res && $subdir1 && ($res = $this->make_dir($subdir1));
			$res && $subdir1 && $subdir2 && ($res = $this->make_dir($subdir2));
		}
		
		return $res;
	}
	
	private function save_to_local($source, $target) {
		if(!$this->is_upload_file($source)) $succeed = false;
		elseif(@copy($source, $target)) $succeed = true;
		elseif(function_exists('move_uploaded_file') && @move_uploaded_file($source, $target))  $succeed = true;
		elseif (@is_readable($source) && (@$fp_s = fopen($source, 'rb')) && (@$fp_t = fopen($target, 'wb'))) {
			while (!feof($fp_s)) {
				$s = @fread($fp_s, 1024 * 512);
				@fwrite($fp_t, $s);
			}
			fclose($fp_s); fclose($fp_t);
			$succeed = true;
		}
		
		if($succeed)  {
			$this->errorcode = 0;
			@chown($target, 'apache');
			@chmod($target, 0755); 
			@unlink($source);
		} else $this->errorcode = 0;
		
		return $succeed;
	}
	
	private function make_dir($dir, $index = true) {
		$res = true;
		
		if(!is_dir($dir)) {
			$res = @mkdir($dir, 0755, true);
			@chown($dir, 'apache');
			$index && @touch($dir.'/index.html');
		}
		
		return $res;
	}
}
?>